﻿using System;
using System.IO;
using ParserGenerator.GrammarConstruction;
using ParserGenerator.Output;
using ParserGenerator.ScannerConstruction;
using ParserGenerator.SyntacticAnalysis;

namespace ParserGenerator.ParserConstruction
{
    [Serializable]
    public sealed class ParserAutomaton
    {
        public GrammarDeclaration Grammar { get; internal set; }
        public GrammarGoalDescriptorTable Goals { get; internal set; }
        public GrammarNonterminalTable Nonterminals { get; internal set; }
        public GrammarTerminalTable Tokens { get; internal set; }
        public GrammarProductionTable Productions { get; internal set; }
        public ScannerAutomaton ScannerAutomaton { get; internal set; }
        public ParserAutomatonStateTable States { get; private set; }
        public ParserAutomatonType AutomatonType { get; private set; }
        public bool UseDefaultReductions { get; private set; }
        public bool IsEmpty => Goals.Count <= 0;

        internal ParserAutomaton()
        {
        }

        internal void Build()
        {
            AutomatonType = Grammar.ParserAutomatonType;
            UseDefaultReductions = Grammar.UseDefaultParserReductions;
            States = new ParserAutomatonStateTable(this);
        }

        public sealed override string ToString()
        {
            using (StringWriter writer = new StringWriter())
            {
                IndentedWriter w = new IndentedWriter(writer);
                ParserAutomatonTextWriter tw = new ParserAutomatonTextWriter(w);
                tw.WriteParserAutomaton(this);
                return writer.ToString().Trim();
            }
        }

        public string ToHtmlString()
        {
            using (StringWriter writer = new StringWriter())
            {
                IndentedWriter w = new IndentedWriter(writer);
                ParserAutomatonHtmlWriter hw = new ParserAutomatonHtmlWriter(w);
                hw.WriteParserAutomaton(this);
                return writer.ToString().Trim();
            }
        }

        public string ToGraphvizString()
        {
            using (StringWriter writer = new StringWriter())
            {
                IndentedWriter w = new IndentedWriter(writer);
                ParserAutomatonGraphvizWriter gw = new ParserAutomatonGraphvizWriter(w);
                gw.WriteParserAutomaton(this);
                return writer.ToString().Trim();
            }
        }
    }
}
